home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Direct Blitting in C++ / Blitting.sit / Blitting ƒ / CCopier.cp < prev    next >
Text File  |  1995-04-21  |  4KB  |  144 lines

  1. // CCopier.cp, the CCopier class methods, for image copying
  2. //
  3. // Copyright ⌐ 1995, Macneil Shonle. All rights reserved.
  4.  
  5. #ifndef __CCOPIER__
  6. #include <CCopier.h>
  7. #endif
  8.  
  9. #ifndef __CDIRECTBLIT__
  10. #include <CDirectBlit.h>
  11. #endif
  12.  
  13. #ifndef __STGWORLDSETTER__
  14. #include <StGWorldSetter.h>
  15. #endif
  16.  
  17. #ifndef __STMMUMODESWAPPER__
  18. #include <StMMUModeSwapper.h>
  19. #endif
  20.  
  21. #ifndef __PIXELTYPES__
  22. #include <PixelTypes.h>
  23. #endif
  24.  
  25. CCopier::CCopier( CDirectBlit *inSource, CDirectBlit *inDest,
  26.                   CopyMethod inCopy, SwapMethod inSwap )
  27. {    mSource = inSource;
  28.     mDest = inDest;
  29.     mCopyMethod = inCopy;
  30.     mSwapMethod = inSwap;
  31. }
  32.  
  33. void CCopier::SetSource( CDirectBlit *inSource )
  34. {    mSource = inSource;
  35. }
  36.  
  37. void CCopier::SetDest( CDirectBlit *inDest )
  38. {    mDest = inDest;
  39. }
  40.  
  41. void CCopier::SetCopyMethod( CopyMethod inCopy )
  42. {    mCopyMethod = inCopy;
  43. }
  44.  
  45. void CCopier::SetSwapMethod( SwapMethod inSwap )
  46. {    mSwapMethod = inSwap;
  47. }
  48.  
  49. void CCopier::operator()( Rect *sourceRect, Rect *destRect )
  50. {    switch( mCopyMethod )
  51.     {    case kDirect8To8:
  52.             Direct8To8Copy( sourceRect, destRect );
  53.             break;
  54.         case kQuickDraw:
  55.             QuickDrawCopy( sourceRect, destRect );
  56.             break;
  57.     }
  58. }
  59.  
  60. void CCopier::Direct8To8Copy( Rect *sourceRect, Rect *destRect )
  61. {    // Init the source and dest pointers
  62.     register FourPixelsPtr source =
  63.         FourPixelsPtr(mSource->GetAddressOfPixel( sourceRect->left, sourceRect->top ));
  64.     
  65.     register FourPixelsPtr dest =
  66.         FourPixelsPtr(mDest->GetAddressOfPixel( destRect->left, destRect->top ));
  67.     
  68.     // Get in the correct addressing mode
  69.     int mode = (mSwapMethod == kAutoSwap) ? (mDest->Use32Bit() | mSource->Use32Bit()) : false;
  70.     StMMUModeSwapper swapTo( mode );
  71.     
  72.     RowWidth copyWidth = destRect->right - destRect->left;
  73.     ColumnHeight numberOfRows = destRect->bottom - destRect->top;
  74.     
  75.     register RowWidth sourceNextRow = mSource->GetRowBytes() - copyWidth;
  76.     register RowWidth destNextRow = mDest->GetRowBytes() - copyWidth;
  77.     
  78.     do
  79.     {    register int width = copyWidth;
  80.         
  81.         // long-word align the address
  82.         int bytesBeforeAlignment = 4 - ( long(source) & 0x3L );
  83.         
  84.         if( bytesBeforeAlignment < 4 )
  85.         {    do
  86.             {    if( width )
  87.                 {    *PixelPtr(dest) = *PixelPtr(source);
  88.                     dest = FourPixelsPtr(PixelPtr(dest) + 1);
  89.                     source = FourPixelsPtr(PixelPtr(source) + 1);
  90.                     --width;
  91.                 }
  92.                 else
  93.                     return;
  94.             } while( --bytesBeforeAlignment );
  95.         }
  96.         
  97.         if( width < 4 )
  98.             goto FinishOffBytes;
  99.         
  100.         // use Duff's device for the pixel chunks
  101.         int chunksToMove = width >> 2;
  102.         int timesCopy = (chunksToMove + 7) >> 3;
  103.         
  104.         switch( chunksToMove & 0x7 )
  105.         {    case 0:    do
  106.                     {    *dest++ = *source++;
  107.             case 7:        *dest++ = *source++;
  108.             case 6:        *dest++ = *source++;
  109.             case 5:        *dest++ = *source++;
  110.             case 4:        *dest++ = *source++;
  111.             case 3:        *dest++ = *source++;
  112.             case 2:        *dest++ = *source++;
  113.             case 1:        *dest++ = *source++;
  114.                     } while( --timesCopy > 0 );
  115.         }
  116.         
  117. FinishOffBytes:
  118.         // move 1, 2 or 3 bytes
  119.         if( width & 1 )
  120.         {    *PixelPtr(dest) = *PixelPtr(source);
  121.             dest = FourPixelsPtr(PixelPtr(dest) + 1);
  122.             source = FourPixelsPtr(PixelPtr(source) + 1);
  123.         }
  124.         
  125.         if( width & 2 )
  126.         {    *TwoPixelsPtr(dest) = *TwoPixelsPtr(source);
  127.             dest = FourPixelsPtr(TwoPixelsPtr(dest) + 1);
  128.             source = FourPixelsPtr(TwoPixelsPtr(source) + 1);
  129.         }
  130.         
  131.         // jump down to the next row
  132.         source = FourPixelsPtr(PixelPtr(source) + sourceNextRow);
  133.         dest = FourPixelsPtr(PixelPtr(dest) + destNextRow);
  134.         
  135.     } while( --numberOfRows );
  136. }
  137.  
  138. void CCopier::QuickDrawCopy( Rect *sourceRect, Rect *destRect )
  139. {    StGWorldSetter setTo( mDest->GetMacPort(), mDest->GetMacDevice() );
  140.     
  141.     ::CopyBits( mSource->GetBitMap(), mDest->GetBitMap(),
  142.                 sourceRect, destRect, srcCopy, nil );
  143. }
  144.